package com.ruoyi.maode.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.enums.ResultEums;
import com.ruoyi.common.enums.TypeEums;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.maode.domain.dto.AddPartMeasureDTO;
import com.ruoyi.maode.domain.dto.ApproveRequestDTO;
import com.ruoyi.maode.domain.dto.DetectionResultDTO;
import com.ruoyi.maode.domain.entity.Part;
import com.ruoyi.maode.domain.entity.PartBatch;
import com.ruoyi.maode.domain.entity.PartMeasure;
import com.ruoyi.maode.domain.entity.PartReport;
import com.ruoyi.maode.domain.vo.ImageDetailVO;
import com.ruoyi.maode.domain.vo.PartSizeDataVO;
import com.ruoyi.maode.domain.vo.PartSizeDetailsVO;
import com.ruoyi.maode.domain.vo.ResultVO;
import com.ruoyi.maode.service.*;
import com.ruoyi.web.core.config.ResultDTO;
import com.ruoyi.web.util.pdf.HtmlToPdfUtils;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 零件检测Controller
 * @author zhangwenqiang
 */

@RestController
@RequestMapping("/partMeasure")
public class PartMeasureController extends BaseController {

    @Autowired
    private PartMeasureService partMeasureService;

    @Autowired
    private PartSizeService partSizeService;

    @Autowired
    private PartService partService;

    @Autowired
    private PartBatchService partBatchService;

    @Autowired
    private PartReportService partReportService;

    @Autowired
    private ApproveRequestProcessService approveRequestProcessService;

    @Value("${ruoyi.profile}")
    private String url;

    @Value("${report-template.path}")
    private String reportTemplatePath;


    @ApiOperation("新增实测数据")
    @PostMapping("/addMeasure")
    public ResultDTO addMeasure(@RequestBody AddPartMeasureDTO dto) {
        Part part = partService.getOne(new LambdaQueryWrapper<Part>().eq(Part::getPartCode, dto.getPartCode()).eq(Part::getIsDelete,Constants.CONSTANTS_ZERO));
        PartBatch partBatch = partBatchService.getOne(new LambdaQueryWrapper<PartBatch>()
                .eq(PartBatch::getBatchCode, dto.getPartBatchCode())
                .eq(PartBatch::getPartId,part.getId()));
        PartMeasure partMeasure = new PartMeasure();
        partMeasure.setPartBatchId(partBatch.getId());
        partMeasure.setPartId(Math.toIntExact(part.getId()));
        List<String> filteredValues = dto.getValue().stream()
                .filter(value -> !value.isEmpty())
                .collect(Collectors.toList());
        // 将实测数据["1","2","3"]转换为"1、2、3"
        String values = filteredValues.stream().collect(Collectors.joining("、"));
        BeanUtils.copyProperties(dto,partMeasure);
        partMeasure.setValue(values.replaceAll(",+$", ""));
        // 获取当前登录人ID--检验人员ID
        partMeasure.setInspectorId(SecurityUtils.getUserId());
        PartMeasure measure = partMeasureService.getOne(new LambdaQueryWrapper<PartMeasure>()
                .eq(PartMeasure::getSizeId, dto.getSizeId())
                .eq(PartMeasure::getPartId,part.getId())
                .eq(PartMeasure::getPartBatchId,partBatch.getId()));
        if (measure != null) {
            return ResultDTO.success(partMeasureService.update(new LambdaUpdateWrapper<PartMeasure>()
                                    .eq(PartMeasure::getSizeId, dto.getSizeId())
                                    .set(PartMeasure::getValue, values)
                                    .set(PartMeasure::getResult, dto.getResult())));
        }
        return ResultDTO.success(partMeasureService.save(partMeasure));
    }

    @ApiOperation("获取检测结果")
    @PostMapping("/getResult")
    public ResultDTO getResult(@RequestBody DetectionResultDTO resultDTO) {
        Boolean result = partMeasureService.getResult(resultDTO);
        String re = Constants.CONSTANTS_ZERO;
        if (result) {
            re = Constants.CONSTANTS_ONE;
        }
        ResultVO resultVO = new ResultVO();
        resultVO.setResult(re);
        resultVO.setSerialNumber(resultDTO.getSerialNumber());
        return ResultDTO.success(resultVO);
    }

    @ApiOperation("生成检测报告")
    @GetMapping("/generateReport/{partBatchId}/{approveState}")
    public ResultDTO generateReport(@PathVariable("partBatchId") Long partBatchId,@PathVariable("approveState")String approveState) {
        // 查询该批次实测数据

        PartBatch partBatch = partBatchService.getOne(new LambdaQueryWrapper<PartBatch>().eq(PartBatch::getId, partBatchId));
        PartSizeDataVO partSizeDataVO = partSizeService.getPartSizeDetail(partBatchId,partBatch.getType(), Math.toIntExact(partBatch.getPartId()));
        partSizeDataVO.setType(partBatch.getType());

        // 生成html文件
        // 1、获取表头数据
        Map<String, String> replacements = new HashMap<>();
        replacements.put("types", "入厂检测报告");
        replacements.put("generateTime", DateUtils.getDate());
        replacements.put("sampleType", TypeEums.fromValue(partSizeDataVO.getType()).getDescription());
        replacements.put("batchNumber", partSizeDataVO.getPartBatchCode());
        replacements.put("productName", partSizeDataVO.getPartName());
        replacements.put("partCode", partSizeDataVO.getPartCode());

        // 2、获取气泡图地址
        List<String> imageUrls = partSizeDataVO.getImageData().stream()
                .map(ImageDetailVO::getUrl)
                .collect(Collectors.toList());
        // 3、获取表格数据
        List<Map<String, String>> tableData = new ArrayList<>();
        for (PartSizeDetailsVO partSizeDetailsVO : partSizeDataVO.getPartSizeData()){
            Map<String, String> row = new HashMap<>();
            row.put("sort", partSizeDetailsVO.getSerialNumber());
            row.put("min", partSizeDetailsVO.getMin());
            row.put("max", partSizeDetailsVO.getMax());
            row.put("job", String.join(",", partSizeDetailsVO.getMeasuredValue()));
            if (partSizeDetailsVO.getResult() != null){
                row.put("result", ResultEums.fromValue(Integer.parseInt(partSizeDetailsVO.getResult())).getDescription());
            }
            tableData.add(row);
        }
        try {
            // 生成html文件
            String generateHtml = HtmlToPdfUtils.generateHtml(reportTemplatePath,imageUrls,tableData,replacements);
            // 保存html文件
            // 保存生成的 HTML 文件
            HtmlToPdfUtils.saveHtmlToFile(generateHtml,  url + "/templates/template.html");
            // 定义报告文件名
            String pdfFileName = generateFileName(partSizeDataVO.getPartCode(),partSizeDataVO.getPartName(),partSizeDataVO.getPartBatchCode());
            // 报告地址
            String reportUrl =  "/report/" + DateUtils.datePath() + "/" +pdfFileName;

            // html文件地址
            String htmlUrl = "/templates/template.html";

            HtmlToPdfUtils.htmlToPdf(url + htmlUrl,url + reportUrl);

            // 报告路径存入数据库
            PartReport partReport = partReportService.getOne(new LambdaQueryWrapper<PartReport>()
                    .eq(PartReport::getBatchId, partSizeDataVO.getPartBatchCode())
                    .eq(PartReport::getPartId, partSizeDataVO.getPartId()));
            if (partReport == null) {
                PartReport partReportData = new PartReport();
                partReportData.setBatchId(partBatchId);
                partReportData.setPartId(partSizeDataVO.getPartId());
                partReportData.setReportUrl("/profile" + reportUrl);
                partReportService.save(partReportData);
            }

            // 批次的检测状态更新为已检
            partBatchService.update(new LambdaUpdateWrapper<PartBatch>()
                    .set(PartBatch::getStatus, Integer.valueOf(Constants.CONSTANTS_TWO))
                    .set(PartBatch::getResult, Integer.valueOf(Constants.CONSTANTS_THREE))
                    .set(PartBatch::getUpdateTime, new Date())
                    .eq(PartBatch::getId, partBatchId));

            // 删除html文件
            new File(url + htmlUrl).delete();

            // 报告生成后创建审批流程
            ApproveRequestDTO approveRequestDTO = new ApproveRequestDTO();
            approveRequestDTO.setBatchId(partBatchId);
            approveRequestDTO.setApprove("发起审批流程");
            approveRequestDTO.setApproveState(approveState);
            approveRequestDTO.setPartBatchCode(partSizeDataVO.getPartBatchCode());
            approveRequestDTO.setPartCode(partSizeDataVO.getPartCode());
            approveRequestProcessService.approveRequest(approveRequestDTO);
            return ResultDTO.success();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResultDTO.success();
    }

    private static String generateFileName(String partCode,String partName,String partBatchCode) {
        return partBatchCode + "_" + partCode+ "_" + partName+".pdf";
    }
}
